package com.ncmem.model;

import com.ncmem.up7.biz.FolderSchema;
import com.ncmem.utils.PathTool;
import com.ncmem.utils.UtilsTool;

import java.io.File;
import java.util.Date;

/*
 * 原型
 * 更新记录：
 * 	2016-01-07
 * 		FileMD5更名为md5
 * 		PostComplete更名为complete
 * 		FileLength更名为lenLoc
 * 		FileSize更名为sizeLoc
 * 		PostedPercent更名为perSvr
 */
public class FileInf {

    public enum StorageType {
        IO,FastDFS,Minio,OSS,OBS;
    }

    public static FileInf build(){return  new FileInf();}

    public FileInf()
    {
    }
    @DataBaseAttribute(name="f_id")
    public String id="";

    @DataBaseAttribute(name="f_pid")
    public String pid="";

    @DataBaseAttribute(name="f_pidRoot")
    public String pidRoot="";

    /**  * 表示当前项是否是一个文件夹项。	*/
    @DataBaseAttribute(name="f_fdTask")
    public boolean fdTask=false;

    /**  * 是否是文件夹中的子文件*/
    @DataBaseAttribute(name="f_fdChild")
    public boolean fdChild=false;
    /**  * 文件块	*/
    @DataBaseAttribute(name="f_blockCount")
    public int blockCount=0;
    @DataBaseAttribute(name="f_blockSize")
    public int blockSize=0;//逻辑分块大小

    @DataBaseAttribute(name="f_blockIndex")
    public int blockIndex=0;

    @DataBaseAttribute(name="f_blockOffset")
    public long blockOffset=0;

    @DataBaseAttribute(name="f_encrypt")
    public boolean encrypt=false;

    /**  * 加密算法类型,aes,sm4	*/
    @DataBaseAttribute(name="f_encryptAlgo")
    public String encryptAgo = "aes";

    /**  * 块加密标识	*/
    public boolean blockEncrypt=false;
    /**  * 块加密大小	*/
    public int blockSizeCry=0;
    /**  * 块压缩大小	*/
    public int blockSizeCpr=0;
    public String object_id="";

    /**  * 块压缩	*/
    public boolean blockCompress = false;
    public String blockCprType = "gzip";

    public int fileCount=0;

    /**  * 用户ID。与第三方系统整合使用。	*/
    @DataBaseAttribute(name="f_uid")
    public String uid="";

    /**  * 文件在本地电脑中的名称	*/
    @DataBaseAttribute(name="f_nameLoc")
    public String nameLoc="";

    /**	 * 文件在服务器中的名称。	 */
    @DataBaseAttribute(name="f_nameSvr")
    public String nameSvr="";

    /**	 * 文件在本地电脑中的完整路径。示例：D:\Soft\QQ2012.exe	 */
    @DataBaseAttribute(name="f_pathLoc")
    public String pathLoc="";

    /**	 * 文件在服务器中的完整路径。示例：F:\\ftp\\uer\\md5.exe	 */
    @DataBaseAttribute(name="f_pathSvr")
    public String pathSvr="";

    /**	 * 文件相对路径(用于层级结构)。示例：md5.exe	 */
    @DataBaseAttribute(name="f_pathRel")
    public String pathRel="";

    /**  * 文件块目录 f:/webapps/files/年/月/日/guid/file-guid/	*/
    public String blockPath = "";

    /**	 * 文件MD5	 */
    @DataBaseAttribute(name="f_md5")
    public String md5="";

    /**	 * 数字化的文件长度。以字节为单位，示例：120125	 */
    @DataBaseAttribute(name="f_lenLoc")
    public long lenLoc=0;

    @DataBaseAttribute(name="f_lenLocSec")
    public long lenLocSec = 0;

    /**	 * 格式化的文件尺寸。示例：10.03MB	 */
    @DataBaseAttribute(name="f_sizeLoc")
    public String sizeLoc="0byte";
    public String sizeSvr="0byte";

    /**	 * 已上传大小。以字节为单位	 */
    @DataBaseAttribute(name="f_lenSvr")
    public long lenSvr=0;

    /**	 * 已上传百分比。示例：10%	 */
    @DataBaseAttribute(name="f_perSvr")
    public String perSvr="0%";

    @DataBaseAttribute(name="f_complete")
    public boolean complete=false;

    @DataBaseAttribute(name="f_time")
    public Date time = new Date();

    @DataBaseAttribute(name="f_deleted")
    public boolean deleted=false;

    /**	 * 是否已经扫描完毕，提供给大型文件夹使用，大型文件夹上传完毕后开始扫描。	 */
    @DataBaseAttribute(name="f_scan")
    public boolean scaned=false;

    /**	 * 存储类型：io,oss,obs,cos,aws。	 */
    @DataBaseAttribute(name="f_storage")
    public String storage="io";

    public StorageType storageType = StorageType.IO;

    /**	 * 对象存储key。	 */
    @DataBaseAttribute(name="f_object_key")
    public String objectKey="";

    /**	 * 对象存储key.url。	 */
    @DataBaseAttribute(name="f_object_url")
    public String objectUrl="";

    /// <summary>
    /// 计算文件加密后的大小，16字节对齐
    /// </summary>
    public void calLenLocSec() {
        long a = this.lenLoc % 16;
        this.lenLocSec = this.lenLoc + (16 - (a > 0 ? a : 16));

        if (this.encryptAgo.equalsIgnoreCase("sm4"))
        {
            this.calLenLocSecSm4();
        }
    }

    /// <summary>
    /// sm4-cbc-pkcs5padding
    /// (块大小* 块对齐大小) + 最后一块对齐大小
    /// </summary>
    public void calLenLocSecSm4()
    {
        //每一块对齐大小
        this.blockSizeCry = UtilsTool.sm4AlignBlockSize(this.blockSize);

        //块总数-1 * 块对齐大小
        this.lenLocSec = (this.blockCount-1) * this.blockSizeCry;

        //最后一块对齐大小
        long lastSize = this.lenLoc % this.blockSize;
        lastSize = UtilsTool.sm4AlignBlockSize((int)lastSize);

        this.lenLocSec += lastSize;
    }

    public String parentDir()
    {
        File f = new File(this.pathSvr);
        return f.getParent().replace('\\', '/');
    }

    public String schemaFile() {
        return this.parentDir().concat("/schema.txt");
    }

    public void saveScheme()
    {
        FolderSchema fs = new FolderSchema();
        this.calLenLocSec();//自动计算文件加密后的大小
        fs.addFile(this);
    }

    public String formatSize(long byteCount)
    {
        return PathTool.BytesToString(byteCount);
    }
}